package br.ufpe.cin.wormbox.core;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;

public class ServicosGerenciamentoArquivo implements Serializable {

	private static final long serialVersionUID = 1717376388652552644L;
	private long ultimaSincronizacao; //Nao vai ser assim guardar em outro lugar
	ArrayList<String> deletarCliente;
	Relatorio relatorio;
	
	public ServicosGerenciamentoArquivo(){
		this.ultimaSincronizacao = 0;
	}

	public void setSync(long sync) {
		this.ultimaSincronizacao = sync;
	}
	
	public long getsync() {
		return this.ultimaSincronizacao;
	}

	private void gerarRelatorio(Arquivo[] cliente, Arquivo[] servidor) {
		int indiceCliente = 0,
				indiceServidor = 0,
				percorrerServidor = 0;
		Arquivo c = null, s = null;

		for(; indiceCliente < cliente.length; indiceCliente++) {
			c = cliente[indiceCliente];

			for(percorrerServidor = indiceServidor; percorrerServidor < servidor.length; percorrerServidor++) {
				s = servidor[percorrerServidor];
				if(c.equals(s)){
					for(; indiceServidor < percorrerServidor; indiceServidor++) {
						//Aqui so tem arquivo que so tem no servidor
						Arquivo s2 = servidor[indiceServidor];
						if(this.ultimaSincronizacao < s2.getUltimaModificacao()) {
							if(s2.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
								this.relatorio.inserirElemento(s2.isEhArquivo(), s2.getCaminhoArquivo(), s2.getUltimaModificacao(), Relatorio.ENVIAR, s2.getNomeArquivo(), s2.getTamanho());
							}else{
								this.gerarRelatorio(new Arquivo[0], s2.getSubs());
							}
						}else{
							if(s2.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
								this.relatorio.inserirElemento(s2.isEhArquivo(), s2.getCaminhoArquivo(), s2.getUltimaModificacao(), Relatorio.DELETAR, s2.getNomeArquivo(), s2.getTamanho());
							}else{
								this.gerarRelatorio(new Arquivo[0], s2.getSubs());
							}
						}
					}

					indiceServidor++;//porque eu nao vou mais usar a pasta sendo comparada atualmente em futuras comparacoes
					percorrerServidor = servidor.length+1;//pra sair do laco que percorre os arquivos do servidor
					
					if(c.getUltimaModificacao() > s.getUltimaModificacao()) {
						//arquivo do cliente mais atualizado
						if(c.getUltimaModificacao() > this.ultimaSincronizacao) {
							if(c.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
								this.relatorio.inserirElemento(c.isEhArquivo(), c.getCaminhoArquivo(), c.getUltimaModificacao(), Relatorio.RECEBER, c.getNomeArquivo(), c.getTamanho());
							}else{
								this.gerarRelatorio(c.getSubs(), s.getSubs());
							}
						} else {
							if(c.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
								this.relatorio.inserirElemento(c.isEhArquivo(), c.getCaminhoArquivo(), c.getUltimaModificacao(), Relatorio.FAZER_NADA, c.getNomeArquivo(), c.getTamanho());
							}else{
								this.gerarRelatorio(c.getSubs(), s.getSubs());
							}
						}
						
					} else if(c.getUltimaModificacao() < s.getUltimaModificacao()) {
						if(s.getUltimaModificacao() > this.ultimaSincronizacao) {
							if(s.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
								this.relatorio.inserirElemento(s.isEhArquivo(), s.getCaminhoArquivo(), s.getUltimaModificacao(), Relatorio.ENVIAR, s.getNomeArquivo(), s.getTamanho());
							}else{
								this.gerarRelatorio(c.getSubs(), s.getSubs());
							}
						} else {
							if(s.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
								this.relatorio.inserirElemento(s.isEhArquivo(), s.getCaminhoArquivo(), s.getUltimaModificacao(), Relatorio.FAZER_NADA, s.getNomeArquivo(), s.getTamanho());
							}else{
								this.gerarRelatorio(c.getSubs(), s.getSubs());
							}
						}
					} else {
						this.relatorio.inserirElemento(c.isEhArquivo(), c.getCaminhoArquivo(), c.getUltimaModificacao(), Relatorio.FAZER_NADA, c.getNomeArquivo(), c.getTamanho());
					}
				}
			}
			if(percorrerServidor == servidor.length) {
				//so tem no cliente
				if(c.getUltimaModificacao() > this.ultimaSincronizacao) {
					if(c.getSubs().length == 0) {
						this.relatorio.inserirElemento(c.isEhArquivo(), c.getCaminhoArquivo(), c.getUltimaModificacao(), Relatorio.RECEBER, c.getNomeArquivo(), c.getTamanho());
					}else{
						this.gerarRelatorio(c.getSubs(), new Arquivo[0]);
					}
				}else if(c.getUltimaModificacao() < this.ultimaSincronizacao){
					if(c.getSubs().length == 0) {
						this.relatorio.inserirElemento(c.isEhArquivo(), c.getCaminhoArquivo(), c.getUltimaModificacao(), Relatorio.DELETAR_CLIENTE, c.getNomeArquivo(), c.getTamanho());
						//this.deletarCliente.add(c.getCaminhoArquivo());
					}else{
						this.gerarRelatorio(c.getSubs(), new Arquivo[0]);
					}
				}
			}
		}
		//trata os arquivos que sobram no servidor
		for(; indiceServidor < servidor.length; indiceServidor++) {
			s = servidor[indiceServidor];
			//Aqui so tem arquivo que so tem no servidor
			if(this.ultimaSincronizacao < s.getUltimaModificacao()) {
				if(s.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
					this.relatorio.inserirElemento(s.isEhArquivo(), s.getCaminhoArquivo(), s.getUltimaModificacao(), Relatorio.ENVIAR, s.getNomeArquivo(), s.getTamanho());
				}else{
					this.gerarRelatorio(new Arquivo[0], s.getSubs());
				}
			}else{
				if(s.getSubs().length == 0) {//eh arquivo ou uma pasta vazia
					this.relatorio.inserirElemento(s.isEhArquivo(), s.getCaminhoArquivo(), s.getUltimaModificacao(), Relatorio.DELETAR, s.getCaminhoArquivo(), s.getTamanho());
				}else{
					this.gerarRelatorio(new Arquivo[0], s.getSubs());
				}
			}
		}
		
		
	}
	
	public Relatorio getRelatorio(Arquivo cliente, Arquivo servidor) {
		this.relatorio = new Relatorio();
		this.deletarCliente = new ArrayList<String>();
		this.gerarRelatorio(cliente.getSubs(), servidor.getSubs());
		
		return this.relatorio;
	}
	
	public static void deletar(File f) {
		if(f.isFile()) {
			f.delete();
		} else {
			File[] listaConteudo = f.listFiles();
			
			for(File conteudo : listaConteudo) {
				deletar(conteudo);
			}
			
			f.delete();
		}
	}
	
	public static void main(String[] args) throws IOException {
	
	}
}


